home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_11_06 / suer01.c < prev    next >
C/C++ Source or Header  |  1993-04-10  |  27KB  |  813 lines

  1.  
  2. /*****************************************************/
  3. /* NATURAL.C   Copyright (c) 1993 Russell Suereth    */
  4. /*****************************************************/
  5.  
  6. /*****************************************************/
  7. /* This is the original natural language processor   */
  8. /* code plus expansions for tense and number.        */
  9. /*****************************************************/
  10.  
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include "natural.h"
  16.  
  17. void initialize(void);
  18. void reset_sentence(void);
  19. void get_record(char *);
  20. char *extract_word(void);
  21. int  match_record(char *, int);
  22. char *extract_root(void);
  23. int  check_underlying(void);
  24. int  check_type(char *,int);
  25. void get_aux(void);
  26. int  match_aux(void);
  27. void check_subject(void);
  28. void check_action(void);
  29. void check_place(void);
  30. void check_aux_verb(void);
  31. void check_number(void);
  32. void make_response(void);
  33. void make_answer(int);
  34. void get_verb(char, char, char);
  35. int  match_verb(char, char, char);
  36.  
  37. FILE *infile;
  38. char dic_record[80];
  39. int  sentence;
  40. int  word_ct;
  41. char word_array[10][25];
  42. char root_array[10][25];
  43. char prime_types[10][11];
  44. char phrases[10][11];
  45. char type_array[10][5][11];
  46. char subjects[20][25];
  47. char actions[20][25];
  48. char places[20][31];
  49. char response[200];
  50. unsigned char verb_tense[5];
  51. unsigned char verb_number[5];
  52. unsigned char verb_usage;
  53. unsigned char aux_tense[5];
  54. unsigned char aux_number[5];
  55. unsigned char aux_usage;
  56. unsigned char subject_number;
  57. unsigned char tenses[20];
  58. unsigned char numbers[20];
  59. unsigned char usages[20];
  60. unsigned char subjects_type[20];
  61. unsigned char aux_meaning[20][5];
  62. char auxiliaries[20][25];
  63.  
  64. void main()
  65. {
  66.     char  *cur_word;
  67.     char  in_sentence[80];
  68.  
  69.     initialize();
  70.     if ((infile = fopen("diction", "r+")) == NULL) {
  71.         printf ("\nError opening dictionary\n");
  72.         exit(0);
  73.     }
  74.     printf("\nSentence: ");
  75.  
  76.     while(gets(in_sentence)) {
  77.         if (in_sentence[0] == '\0') break;
  78.         reset_sentence();
  79.  
  80.         cur_word = strtok(in_sentence, " ");
  81.         while(cur_word != NULL) {
  82.             get_record(cur_word);
  83.             cur_word = strtok(NULL, " ");
  84.             if (++word_ct > 9) break;
  85.         }
  86.  
  87.         if (check_underlying() == 0) {
  88.             check_subject();
  89.             check_action();
  90.             check_place();
  91.             check_aux_verb();
  92.             check_number();
  93.         }
  94.  
  95.         make_response();
  96.  
  97.         printf("Response: %s\n\nSentence: ", response);
  98.  
  99.         if (++sentence > 19) break;
  100.     }   /*  end while  */
  101.  
  102.     fclose(infile);
  103.     return;
  104. }
  105.  
  106. /*****************************************************/
  107. /* Initialize variables.                             */
  108. /*****************************************************/
  109. void initialize()
  110. {
  111.     sentence              = 0;
  112.     memset(subjects,      '\0', 500);
  113.     memset(actions,       '\0', 500);
  114.     memset(places,        '\0', 620);
  115.     memset(tenses,        '\0',  20);
  116.     memset(numbers,       '\0',  20);
  117.     memset(usages,        '\0',  20);
  118.     memset(subjects_type, '\0',  20);
  119.     memset(aux_meaning,   '\0', 100);
  120.     memset(auxiliaries,   '\0', 500);
  121.     return;
  122. }
  123.  
  124. /*****************************************************/
  125. /* These variables are initialized for each new      */
  126. /* input sentence.                                   */
  127. /*****************************************************/
  128. void reset_sentence()
  129. {
  130.     word_ct                      = 0;
  131.     memset(word_array,    '\0', 250);
  132.     memset(root_array,    '\0', 250);
  133.     memset(prime_types,   '\0', 110);
  134.     memset(phrases,       '\0', 110);
  135.     memset(type_array,    '\0', 550);
  136.     response[0]               = '\0';
  137.     return;
  138. }
  139.  
  140. /*****************************************************/
  141. /* Get all the records from the dictionary. If the   */
  142. /* passed word is not in the dictionary, then the    */
  143. /* word could be a name.                             */
  144. /*****************************************************/
  145. void get_record(char *pass_word)
  146. {
  147.     int types = 0;
  148.     rewind (infile);
  149.     fgets(dic_record, 80, infile);
  150.     while (! feof(infile)) {
  151.         if (match_record(pass_word, types) == 0)
  152.             types++;
  153.         fgets(dic_record, 80, infile);
  154.     }
  155.     if (types == 0) {
  156.         if (isupper( (int) pass_word[0]))
  157.             strcpy(type_array[word_ct][types], "NAME");
  158.         else
  159.             strcpy(type_array[word_ct][types],
  160.                    "NOTFOUND");
  161.     }
  162.     strcpy(word_array[word_ct], pass_word);
  163.     return;
  164. }
  165.  
  166. /*****************************************************/
  167. /* Compare the passed word with the word in the      */
  168. /* current dictionary record. If they are the same,  */
  169. /* then extract the type (NOUN, VERB, etc.). If the  */
  170. /* type is PRON, then extract pronoun information.   */
  171. /* If the type is VERB, then extract verb            */
  172. /* information.                                      */
  173. /*****************************************************/
  174. int  match_record(char *pass_word, int types)
  175. {
  176.     int i, j;
  177.     char *root;
  178.     char *dic_word;
  179.     dic_word = extract_word();
  180.     /* Check if passed word equals dictionary word   */
  181.     if (strcmpi(pass_word, dic_word) != 0) return(1);
  182.  
  183.     /* Word found, get the type                      */
  184.     for (i=24,j=0; i<28; i++) {
  185.        if (isspace(dic_record[i])) break;
  186.        type_array[word_ct][types][j++] = dic_record[i];
  187.     }
  188.     /* Trim the type                                 */
  189.     type_array[word_ct][types][j] = '\0';
  190.  
  191.     if (strcmp(type_array[word_ct][types],
  192.                 "PRON") == 0)
  193.         subject_number = dic_record[41];
  194.  
  195.     if (strcmp(type_array[word_ct][types],
  196.                 "VERB") == 0) {
  197.         root = extract_root();
  198.         strcpy(root_array[word_ct], root);
  199.         verb_usage  = dic_record[29];
  200.         for (i=30,j=0; i<34; i++,j++) {
  201.            if (isspace(dic_record[i])) break;
  202.            verb_tense[j] = dic_record[i];
  203.         }
  204.         verb_tense[j] = '\0';
  205.         for (i=41,j=0; i<43; i++,j++) {
  206.            if (isspace(dic_record[i])) break;
  207.            verb_number[j] = dic_record[i];
  208.         }
  209.         verb_number[j] = '\0';
  210.     }
  211.  
  212.     return(0);
  213. }
  214.  
  215. /*****************************************************/
  216. /* Extract the word from the dictionary. The word is */
  217. /* 24 characters in length and starts in column 1.   */
  218. /*****************************************************/
  219. char *extract_word()
  220. {
  221.     int i;
  222.     char dic_word[25];
  223.     strncpy(dic_word, dic_record, 24);
  224.     for (i=23; i>=0; i--) {
  225.         if (isspace(dic_word[i])) {
  226.             dic_word[i] = '\0';
  227.             continue;
  228.         }
  229.         break;
  230.     }
  231.     return(dic_word);
  232. }
  233.  
  234. /*****************************************************/
  235. /* Extract the root from the dictionary. It          */
  236. /* identifies a group of similar words (the root for */
  237. /* run, ran, runs and running is run). It is 14      */
  238. /* characters in length and starts in column 47.     */
  239. /*****************************************************/
  240. char *extract_root()
  241. {
  242.     int i, j;
  243.     char root[15];
  244.     for (i=46,j=0; i<60; i++) {
  245.         if (isspace(dic_record[i])) break;
  246.         root[j++] = dic_record[i];
  247.     }
  248.     /* Trim the root                                 */
  249.     root[j] = '\0';
  250.     return(root);
  251. }
  252.  
  253. /*****************************************************/
  254. /* Determine if the input sentence contains a known, */
  255. /* underlying structure. If it does, then assign the */
  256. /* correct types and phrases for the words.          */
  257. /*****************************************************/
  258. int  check_underlying()
  259. {
  260.     int i = 0;
  261.  
  262.     /* Structure WH-AUX-PRON-VERB                    */
  263.     if ( (check_type("WH",     i) == 0) &&
  264.          (check_type("AUX",  i+1) == 0) &&
  265.          (check_type("PRON", i+2) == 0) &&
  266.          (check_type("VERB", i+3) == 0) ) {
  267.         strcpy(prime_types[i],   "WH");
  268.         strcpy(prime_types[i+1], "AUX");
  269.         strcpy(prime_types[i+2], "PRON");
  270.